'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Public Class Snac0107
    Inherits Snac

    Public Sub New()
        MyBase.New(&H1, &H7)
    End Sub

    Private _RateClasses As New List(Of RateClass)
    Public ReadOnly Property RateClasses() As List(Of RateClass)
        Get
            Return _RateClasses
        End Get
    End Property

    Private _RateGroups As New List(Of RateGroup)
    Public ReadOnly Property RateGroups() As List(Of RateGroup)
        Get
            Return _RateGroups
        End Get
    End Property

    Public Overrides Sub Deserialize(ByVal data As System.Collections.Generic.List(Of Byte))
        MyBase.Deserialize(data)

        Dim index As Integer = Snac.SizeFixPart

        Dim classCount As Integer = ByteConverter.ToUInt16(data.GetRange(index, 2))
        index += 2

        Dim classIndex As Integer = 0

        Do While classIndex < classCount
            Dim cls As RateClass
            cls = New RateClass
            cls.Deserialize(data.GetRange(index, data.Count - index))

            _RateClasses.Add(cls)

            index += cls.TotalSize
            classIndex += 1
        Loop

        Do While index + 4 <= data.Count
            Dim group As RateGroup
            group = New RateGroup
            group.Deserialize(data.GetRange(index, data.Count - index))

            _RateGroups.Add(group)

            index += group.TotalSize
        Loop

        SetTotalSize(index)
    End Sub

    Public Overrides Function Serialize() As System.Collections.Generic.List(Of Byte)
        Throw New NotImplementedException
    End Function

    Public Overrides Function CalculateDataSize() As Integer
        Dim size As Integer = 2
        For Each x As RateClass In _RateClasses
            size += x.CalculateTotalSize
        Next
        For Each x As RateGroup In _RateGroups
            size += x.CalculateTotalSize
        Next
        Return size
    End Function
End Class

Public Class RateClass
    Implements ISerializable

    Public ReadOnly Property TotalSize() As Integer Implements ISerializable.TotalSize
        Get
            Return DataSize
        End Get
    End Property

    Private _DataSize As Integer
    Public ReadOnly Property DataSize() As Integer Implements ISerializable.DataSize
        Get
            Return _DataSize
        End Get
    End Property

    Public Function CalculateDataSize() As Integer Implements ISerializable.CalculateDataSize
        Return 35
    End Function

    Public Function CalculateTotalSize() As Integer Implements ISerializable.CalculateTotalSize
        Return CalculateDataSize()
    End Function

    Public Sub Deserialize(ByVal data As System.Collections.Generic.List(Of Byte)) Implements ISerializable.Deserialize
        Dim index As Integer = 0

        _ClassId = ByteConverter.ToUInt16(data.GetRange(index, 2))
        index += 2

        _WindowSize = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _ClearLevel = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _AlertLevel = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _LimitLevel = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _DisconnectLevel = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _CurrentLevel = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _MaxLevel = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _LastTime = ByteConverter.ToUInt32(data.GetRange(index, 4))
        index += 4

        _CurrentState = data(index)
        index += 1

        _DataSize = index
        _HasData = True
    End Sub

    Public Function Serialize() As System.Collections.Generic.List(Of Byte) Implements ISerializable.Serialize
        Throw New NotImplementedException
    End Function

    Private _ClassId As Long
    Public Property ClassId() As Long
        Get
            Return _ClassId
        End Get
        Set(ByVal value As Long)
            _ClassId = value
        End Set
    End Property

    Private _WindowSize As Long
    Public Property WindowSize() As Long
        Get
            Return _WindowSize
        End Get
        Set(ByVal value As Long)
            _WindowSize = value
        End Set
    End Property

    Private _ClearLevel As Long
    Public Property ClearLevel() As Long
        Get
            Return _ClearLevel
        End Get
        Set(ByVal value As Long)
            _ClearLevel = value
        End Set
    End Property

    Private _AlertLevel As Long
    Public Property AlertLevel() As Long
        Get
            Return _AlertLevel
        End Get
        Set(ByVal value As Long)
            _AlertLevel = value
        End Set
    End Property

    Private _LimitLevel As Long
    Public Property LimitLevel() As Long
        Get
            Return _LimitLevel
        End Get
        Set(ByVal value As Long)
            _LimitLevel = value
        End Set
    End Property

    Private _DisconnectLevel As Long
    Public Property DisconnectLevel() As Long
        Get
            Return _DisconnectLevel
        End Get
        Set(ByVal value As Long)
            _DisconnectLevel = value
        End Set
    End Property

    Private _CurrentLevel As Long
    Public Property CurrentLevel() As Long
        Get
            Return _CurrentLevel
        End Get
        Set(ByVal value As Long)
            _CurrentLevel = value
        End Set
    End Property

    Private _MaxLevel As Long
    Public Property MaxLevel() As Long
        Get
            Return _MaxLevel
        End Get
        Set(ByVal value As Long)
            _MaxLevel = value
        End Set
    End Property

    Private _LastTime As Long
    Public Property LastTime() As Long
        Get
            Return _LastTime
        End Get
        Set(ByVal value As Long)
            _LastTime = value
        End Set
    End Property

    Private _CurrentState As Byte
    Public Property CurrentState() As Byte
        Get
            Return _CurrentState
        End Get
        Set(ByVal value As Byte)
            _CurrentState = value
        End Set
    End Property

    Private _HasData As Boolean

    Public ReadOnly Property HasData() As Boolean Implements ISerializable.HasData
        Get
            Return _HasData
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return String.Format("Window size: {0}\nClear level: {1}\nAlert level: {2}\n" & _
                             "Limit level: {3}\nDisconnect level: {4}\nCurrent level: {5}\n" & _
                             "Max level: {6}\nLast time: {7}", WindowSize, ClearLevel, _
                             AlertLevel, LimitLevel, DisconnectLevel, CurrentLevel, _
                             MaxLevel, LastTime).Replace("\n", Environment.NewLine)
    End Function
End Class

Public Class RateGroup
    Implements ISerializable

    Private _GroupId As Integer
    Public Property GroupId() As Integer
        Get
            Return _GroupId
        End Get
        Set(ByVal value As Integer)
            _GroupId = value
        End Set
    End Property

    Private _ServiceFamilyIdSubTypeIdPairs As New List(Of FamilySubtypePair)
    Public ReadOnly Property ServiceFamilyIdSubTypeIdPairs() As List(Of FamilySubtypePair)
        Get
            Return _ServiceFamilyIdSubTypeIdPairs
        End Get
    End Property

    Public ReadOnly Property TotalSize() As Integer Implements ISerializable.TotalSize
        Get
            Return 4 + DataSize
        End Get
    End Property

    Private _DataSize As Integer
    Public ReadOnly Property DataSize() As Integer Implements ISerializable.DataSize
        Get
            Return _DataSize
        End Get
    End Property

    Public Sub Deserialize(ByVal data As System.Collections.Generic.List(Of Byte)) Implements ISerializable.Deserialize
        Dim pairCount As Integer
        Dim pairIndex As Integer
        Dim index As Integer

        _GroupId = ByteConverter.ToUInt16(data.GetRange(0, 2))
        pairCount = ByteConverter.ToUInt16(data.GetRange(2, 2))

        index = 4

        Do While pairIndex < pairCount
            Dim familyId As Integer = ByteConverter.ToUInt16(data.GetRange(index, 2))
            Dim subtypeId As Integer = ByteConverter.ToUInt16(data.GetRange(index + 2, 2))

            _ServiceFamilyIdSubTypeIdPairs.Add(New FamilySubtypePair(familyId, subtypeId))

            pairIndex += 1
            index += 4
        Loop

        _DataSize = index - 4
        _HasData = True
    End Sub

    Public Function Serialize() As System.Collections.Generic.List(Of Byte) Implements ISerializable.Serialize
        Throw New NotImplementedException
    End Function

    Private _HasData As Boolean

    Public ReadOnly Property HasData() As Boolean Implements ISerializable.HasData
        Get
            Return _HasData
        End Get
    End Property

    Public Function CalculateDataSize() As Integer Implements ISerializable.CalculateDataSize
        Return _ServiceFamilyIdSubTypeIdPairs.Count * 4
    End Function

    Public Function CalculateTotalSize() As Integer Implements ISerializable.CalculateTotalSize
        Return 4 + CalculateDataSize()
    End Function
End Class

Public Class FamilySubtypePair
    Public Sub New(ByVal family As Integer, ByVal subtype As Integer)
        _FamilyId = family
        _SubtypeId = subtype
    End Sub

    Private _FamilyId As Integer
    Public Property FamilyId() As Integer
        Get
            Return _FamilyId
        End Get
        Set(ByVal value As Integer)
            _FamilyId = value
        End Set
    End Property

    Private _SubtypeId As Integer
    Public Property SubtypeId() As Integer
        Get
            Return _SubtypeId
        End Get
        Set(ByVal value As Integer)
            _SubtypeId = value
        End Set
    End Property
End Class